package com.example.stock.service.impl;

import com.example.stock.comm.StrategyEnum;
import com.example.stock.service.IServiceCalc;
import com.example.stock.util.CalcUtil;
import com.example.stock.util.ValidUtil;
import com.example.stock.vo.DataVo;
import com.example.stock.vo.EmaTradeVo;
import com.example.stock.vo.common.TradeVo;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ServiceCalcImpl implements IServiceCalc {

    @Override
    public Map<String, List<TradeVo>> doMultiCalc(Map<String, List<DataVo>> closeDataMap, int m, int n, StrategyEnum strategy) {
        Map<String, List<TradeVo>> ret = new HashMap<>();
        closeDataMap.forEach((tsCode, dataVos) -> {
            List<TradeVo> tradeVos = doCalcOne(dataVos, m, n, strategy);
            ret.put(tsCode, tradeVos);
        });
        return ret;
    }

    @Override
    public List<TradeVo> doCalcOne(List<DataVo> dataVos, int m, int n ,StrategyEnum strategy) {
        List<TradeVo> tradeVos;
        switch (strategy) {
            case EMA_UP: //1
                tradeVos = calcEmaUpTrade1(dataVos, m, n);
                break;
            case MA_UP:  //1
                tradeVos = calcMaUpTrade(dataVos, m, n);
                break;
            case EMA_REF0: //1
                tradeVos = calcEmaRef0Trade(dataVos, m, n);
                break;
            case MA_CROSS:  //1
                tradeVos = calcMaCrossTrade(dataVos, m, n);
                break;
            case MA_PURE:  //1
                tradeVos = calcMaPureTrade(dataVos, m);
                break;
            case EMA_PURE:
                tradeVos = calcEMaPureTrade(dataVos, m);
                break;
            case EMA_UP_COMPLEX:
                tradeVos = calcEmaUpTradeComplex(dataVos, 38, 46, m, n);
                break;
            case DEA_UP:
                tradeVos = calcEdaUpTrade(dataVos,m,n,9);
                break;
            case EMA_UP2:
                tradeVos = calcEdaUp2Trade(dataVos,m,n);
                break;
            case EMA_UP_HEAD:
                tradeVos = calcEdaUpHeadTrade(dataVos,m,n);
                break;
            case EMA_UP_REF:
                tradeVos = calcEdaUpRef(dataVos,38, 46, m);
                break;

            case EMA_UP_SIMPLE:
                tradeVos = calcEdaUpSimpleTrade(dataVos,m,n);
                break;

            case EMA_UP_SS:
                tradeVos = calcEdaUpSSTrade(dataVos,m,n);
                break;

            case EMA_UP_CLOSE:
                tradeVos = calcEdaUpCloseTrade(dataVos,m,n);
                break;

            default:
                throw new RuntimeException("枚举有误");

        }
        return tradeVos;
    }

    private List<TradeVo> calcEdaUpCloseTrade(List<DataVo> closeData, int m, int n) {
        List<DataVo> emaMap = CalcUtil.EMA(CalcUtil._CHU(CalcUtil._CHENG(CalcUtil._JIAN(closeData, CalcUtil.MA(closeData, m)), 1000), closeData), n);

        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo close = closeData.get(i);
            DataVo ema = emaMap.get(i);
            DataVo emaUp = emaUpMap.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    private List<TradeVo> calcEdaUpSSTrade(List<DataVo> dataVos, int m, int n) {
        List<DataVo> emaMap = CalcUtil.EMA(dataVos, m);
        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < dataVos.size(); i++) {
            DataVo close = dataVos.get(i);
            DataVo ema = emaMap.get(i);
            DataVo emaUp = emaUpMap.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;

    }

    //EMA(CLOSE-MA(CLOSE,M),N) :
    private List<TradeVo> calcEdaUpSimpleTrade(List<DataVo> dataVos, int m, int n) {
        List<DataVo> emaMap = CalcUtil.EMA(CalcUtil._JIAN(dataVos, CalcUtil.MA(dataVos, m)), n);
        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < dataVos.size(); i++) {
            DataVo close = dataVos.get(i);
            DataVo ema = emaMap.get(i);
            DataVo emaUp = emaUpMap.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;

    }

    private List<TradeVo> calcEdaUpRef(List<DataVo> dataVos, int m, int n, double ref) {
        boolean hold = false;
        List<DataVo> emaMap = getEmaMap(dataVos, m, n);

        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < dataVos.size(); i++) {
            DataVo close = dataVos.get(i);
            DataVo ema = emaMap.get(i);
            DataVo emaUp = emaUpMap.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            boolean canBuy = emaTradeVo.getUpDown() > 0d;
            if (ema.getPrice() < ref) {
                emaTradeVo.setCanBuy(canBuy);
                hold = canBuy;
            }else {
                if (canBuy == true && hold == true) {
                    emaTradeVo.setCanBuy(true);
                }else {
                    emaTradeVo.setCanBuy(false);
                    hold = false;
                }
//                if (canBuy == false && hold == true) {
//                    emaTradeVo.setCanBuy(false);
//                    hold = false;
//                }
//                if (canBuy == true && hold == false) {
//                    emaTradeVo.setCanBuy(false);
//                    hold = false;
//                }
            }
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    private List<TradeVo> calcEdaUpHeadTrade(List<DataVo> closeData, int m, int n) {

        List<DataVo> emaMap = CalcUtil.EMA(CalcUtil._CHU(CalcUtil._CHENG(CalcUtil._JIAN(closeData, CalcUtil.EMA(closeData, m)), 1000), CalcUtil.EMA(closeData, m)), n);


        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo close = closeData.get(i);
            DataVo ema = emaMap.get(i);
            DataVo emaUp = emaUpMap.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    //JJ:=EMA((CLOSE-MA(CLOSE,M))*1000/MA(CLOSE,M),N),LINETHICK2,COLOR0000FF;
    //散:=JJ-REF(JJ,1);
    private List<TradeVo> calcEdaUp2Trade(List<DataVo> closeData, int m, int n) {

        List<DataVo> emaMap = CalcUtil.EMA(
                CalcUtil._CHU(CalcUtil._CHENG(CalcUtil._JIAN(CalcUtil.MA(closeData, 2), CalcUtil.MA(closeData, m)), 1000), CalcUtil.MA(CalcUtil.MA(closeData, 2), m)),
                n);

        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo close = closeData.get(i);
            DataVo ema = emaMap.get(i);
            DataVo emaUp = emaUpMap.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;

    }


    //JJ:=EMA((CLOSE-MA(CLOSE,M))*1000/MA(CLOSE,M),N),LINETHICK2,COLOR0000FF;
    //散:=JJ-REF(JJ,1);
    public List<TradeVo> calcEmaUpTrade(List<DataVo> closeData, int m, int n) {

        List<DataVo> emaMap3000 = getEmaMap3000(closeData, m, n);

        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap3000, CalcUtil.REF(emaMap3000, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo close = closeData.get(i);
            DataVo ema = emaMap3000.get(i);
            DataVo emaUp = emaUpMap.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    //JJ:=EMA((CLOSE-MA(CLOSE,M))*1000/MA(CLOSE,M),N),LINETHICK2,COLOR0000FF;
    //散:=JJ-REF(JJ,1);
    public List<TradeVo> calcEmaUpTrade1(List<DataVo> closeData, int m, int n) {

        List<DataVo> emaMap1 = getEmaMap3000(closeData, m, n);
        List<DataVo> emaMap = getEmaMap(closeData, m, n);

        List<DataVo> emaUpMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();

        for (int i = 0; i < closeData.size(); i++) {
            DataVo close = closeData.get(i);
            DataVo ema = emaMap.get(i);
            DataVo emaUp = emaUpMap.get(i);
            DataVo emaMap3000 = emaMap1.get(i);
            if (!(close.getTradeTime().equals(ema.getTradeTime()) && close.getTradeTime().equals(emaUp.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(ema.getPrice());
            emaTradeVo.setCalc2(emaMap3000.getPrice());
            emaTradeVo.setUpDown(emaUp.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    //JJ:=EMA((CLOSE-MA(CLOSE,M))*1000/MA(CLOSE,M),N),LINETHICK2,COLOR0000FF;
    //散:=JJ-REF(JJ,1);
    //单计算结果 jj> ref时  ,,,,, 则股票买卖逻辑参考ma线
    public List<TradeVo> calcEmaUpTradeComplex(List<DataVo> closeData, int m, int n, int ref, int ma) {
        List<DataVo> emaMap = getEmaMap(closeData, m, n);
        List<DataVo> maMap = CalcUtil.MA(closeData, ma);
        List<DataVo> upDownMap = CalcUtil._JIAN(emaMap, CalcUtil.REF(emaMap, 1));


        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {

            //均线值
            DataVo dataMa = maMap.get(i);
            //收盘价
            DataVo close = closeData.get(i);
            //收敛值
            DataVo dataEma = emaMap.get(i);

            DataVo upDown = upDownMap.get(i);


            if (!(close.getTradeTime().equals(dataEma.getTradeTime())
                    && close.getTradeTime().equals(upDown.getTradeTime())
                    && close.getTradeTime().equals(dataMa.getTradeTime()))) {

                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }

            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(close.getTradeTime());
            emaTradeVo.setPrice(close.getPrice());
            emaTradeVo.setCalc1(dataEma.getPrice());
            emaTradeVo.setUpDown(upDown.getPrice());
            boolean canBuy = false;
            if (emaTradeVo.getUpDown() > 0d) {
                canBuy = true;
            } else if (dataEma.getPrice() > ref && close.getPrice() > dataMa.getPrice()) {
                canBuy = true;
            }
            emaTradeVo.setCanBuy(canBuy);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    //JJ:=EMA((CLOSE-MA(CLOSE,M))*1000/MA(CLOSE,M),N),LINETHICK2,COLOR0000FF;
    // jj:= EMA(CLOSE-MA(CLOSE,M),N)
    private List<DataVo> getEmaMap(List<DataVo> closeMap, int m, int n) {
        // CLOSE    MA(CLOSE,m)         MA(CLOSE,M)
        return CalcUtil.EMA(CalcUtil._JIAN(closeMap, CalcUtil.MA(closeMap, m)), n);
//        return CalcUtil.EMA(CalcUtil._CHU(CalcUtil._CHENG(CalcUtil._JIAN(closeMap, CalcUtil.MA(closeMap, m)), 1000), CalcUtil.MA(closeMap, m)), n);
    }

    //JJ:=EMA((CLOSE-MA(CLOSE,M))*1000/MA(CLOSE,M),N),LINETHICK2,COLOR0000FF;
    // jj:= EMA(CLOSE-MA(CLOSE,M),N)
    private List<DataVo> getEmaMap3000(List<DataVo> closeMap, int m, int n) {
        // CLOSE    MA(CLOSE,m)         MA(CLOSE,M)
        return CalcUtil._CHENG(CalcUtil._CHU(CalcUtil.EMA(CalcUtil._JIAN(closeMap, CalcUtil.MA(closeMap, m)), n),closeMap),3000);
//        return CalcUtil.EMA(CalcUtil._CHU(CalcUtil._CHENG(CalcUtil._JIAN(closeMap, CalcUtil.MA(closeMap, m)), 1000), CalcUtil.MA(closeMap, m)), n);
    }

    private List<DataVo> get_ma_san_Map(List<DataVo> closeMap, int m, int n) {
        // CLOSE    MA(CLOSE,m)         MA(CLOSE,M)
        return CalcUtil.MA(CalcUtil._CHU(CalcUtil._CHENG(CalcUtil._JIAN(closeMap, CalcUtil.MA(closeMap, m)), 1000), CalcUtil.MA(closeMap, m)), n);
    }


    //通过判断ema散户指标是否上穿线作为买卖依据

    //散户指标://JJ:=EMA((CLOSE-MA(CLOSE,M))*1000/MA(CLOSE,M),N),LINETHICK2,COLOR0000FF;
    public List<TradeVo> calcEmaRef0Trade(List<DataVo> closeData, int m, int n) {
        List<DataVo> _san_Map = getEmaMap(closeData, m, n);
        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo dataVo = closeData.get(i);
            DataVo _san_ = _san_Map.get(i);
            if (!(dataVo.getTradeTime().equals(_san_.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(dataVo.getTradeTime());
            emaTradeVo.setPrice(dataVo.getPrice());
            emaTradeVo.setCalc1(_san_.getPrice());
            emaTradeVo.setCanBuy(_san_.getPrice() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    //判断ma线上杨下杨为买卖依据
    public List<TradeVo> calcMaPureUpTrade(List<DataVo> closeData, int m) {
        List<DataVo> maVos = CalcUtil.MA(closeData, m);
        List<DataVo> upDownMap = CalcUtil._JIAN(maVos, CalcUtil.REF(maVos, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo dataVo = closeData.get(i);
            DataVo maVo = maVos.get(i);
            DataVo upDown = upDownMap.get(i);
            if (!(dataVo.getTradeTime().equals(maVo.getTradeTime()) && dataVo.getTradeTime().equals(upDown.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo maTradeVo = new EmaTradeVo();
            maTradeVo.setTradeTime(dataVo.getTradeTime());
            maTradeVo.setPrice(dataVo.getPrice());
            maTradeVo.setCalc1(maVo.getPrice());
            maTradeVo.setUpDown(upDown.getPrice());
            maTradeVo.setCanBuy(maTradeVo.getUpDown() > 0d);
            emaTradeVos.add(maTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    //双ma线 交叉为买卖依据
    public List<TradeVo> calcMaCrossTrade(List<DataVo> closeData, int m, int n) {
        List<DataVo> mVos = CalcUtil.MA(closeData, m);
        List<DataVo> nVos = CalcUtil.MA(closeData, n);

        List<TradeVo> tradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo dataVo = closeData.get(i);
            DataVo mVo = mVos.get(i);
            DataVo nVo = nVos.get(i);
            if (!(dataVo.getTradeTime().equals(mVo.getTradeTime()) && dataVo.getTradeTime().equals(nVo.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            TradeVo tradeVo = new TradeVo();
            tradeVo.setTradeTime(dataVo.getTradeTime());
            tradeVo.setPrice(dataVo.getPrice());
            tradeVo.setCanBuy(nVo.getPrice() >= mVo.getPrice());
            tradeVos.add(tradeVo);
        }
        ValidUtil.validTimeTrade(tradeVos);
        return tradeVos;
    }

    //通过判断股价是否站上均线
    public List<TradeVo> calcMaPureTrade(List<DataVo> closeData, int m) {
        List<DataVo> mVos = CalcUtil.MA(closeData, m);

        List<TradeVo> tradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo dataVo = closeData.get(i);
            DataVo mVo = mVos.get(i);
            if (!(dataVo.getTradeTime().equals(mVo.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            TradeVo tradeVo = new TradeVo();
            tradeVo.setTradeTime(dataVo.getTradeTime());
            tradeVo.setPrice(dataVo.getPrice());
            tradeVo.setCanBuy(mVo.getPrice() <= dataVo.getPrice());
            tradeVos.add(tradeVo);
        }
        ValidUtil.validTimeTrade(tradeVos);
        return tradeVos;
    }

    public List<TradeVo> calcEMaPureTrade(List<DataVo> closeData, int m) {
        List<DataVo> mVos = CalcUtil.EMA(closeData, m);

        List<TradeVo> tradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo dataVo = closeData.get(i);
            DataVo mVo = mVos.get(i);
            if (!(dataVo.getTradeTime().equals(mVo.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            TradeVo tradeVo = new TradeVo();
            tradeVo.setTradeTime(dataVo.getTradeTime());
            tradeVo.setPrice(dataVo.getPrice());
            tradeVo.setCanBuy(mVo.getPrice() <= dataVo.getPrice());
            tradeVos.add(tradeVo);
        }
        ValidUtil.validTimeTrade(tradeVos);
        return tradeVos;
    }

    //macd 中的 eda  LONG=26 SHORT=12 M=9
    //DIFF:=EMA(CLOSE,SHORT) - EMA(CLOSE,LONG);
    //DEA  := EMA(DIFF,M);
    //MACD := 2*(DIFF-DEA);
    //ENTERLONG:CROSS(MACD,0);
    //EXITLONG:CROSS(0,MACD);
    private List<TradeVo> calcEdaUpTrade(List<DataVo> dataVos, int m, int n,int o) {
        List<DataVo> DIFF = CalcUtil._JIAN(CalcUtil.EMA(dataVos,m),CalcUtil.EMA(dataVos,n));
        List<DataVo> DEA  = CalcUtil.EMA(DIFF,o);
        List<DataVo> DEA_UP = CalcUtil._JIAN(DEA, CalcUtil.REF(DEA, 1));
        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < dataVos.size(); i++) {
            DataVo dataVo = dataVos.get(i);
            DataVo dea = DEA.get(i);
            DataVo upDown = DEA_UP.get(i);
            if (!(dataVo.getTradeTime().equals(dea.getTradeTime()) && dataVo.getTradeTime().equals(upDown.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(dataVo.getTradeTime());
            emaTradeVo.setPrice(dataVo.getPrice());
            emaTradeVo.setCalc1(dea.getPrice());
            emaTradeVo.setUpDown(upDown.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }

    //判断ma线上杨下杨为买卖依据
    public List<TradeVo> calcMaUpTrade(List<DataVo> closeData, int m, int n) {
        List<DataVo> _san_Map = get_ma_san_Map(closeData, m, n);
        List<DataVo> upDownMap = CalcUtil._JIAN(_san_Map, CalcUtil.REF(_san_Map, 1));

        List<TradeVo> emaTradeVos = new ArrayList<>();
        for (int i = 0; i < closeData.size(); i++) {
            DataVo dataVo = closeData.get(i);
            DataVo _san_ = _san_Map.get(i);
            DataVo upDown = upDownMap.get(i);
            if (!(dataVo.getTradeTime().equals(_san_.getTradeTime()) && dataVo.getTradeTime().equals(upDown.getTradeTime()))) {
                throw new RuntimeException("计算出错!! location: com.example.stock.entity.service.StockStatService.calcTrade");
            }
            EmaTradeVo emaTradeVo = new EmaTradeVo();
            emaTradeVo.setTradeTime(dataVo.getTradeTime());
            emaTradeVo.setPrice(dataVo.getPrice());
            emaTradeVo.setCalc1(_san_.getPrice());
            emaTradeVo.setUpDown(upDown.getPrice());
            emaTradeVo.setCanBuy(emaTradeVo.getUpDown() > 0d);
            emaTradeVos.add(emaTradeVo);
        }
        ValidUtil.validTimeTrade(emaTradeVos);
        return emaTradeVos;
    }
}
